home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
bipl.zip
/
PROGS.ZIP
/
EMPG.ICN
< prev
next >
Wrap
Text File
|
1992-09-28
|
8KB
|
211 lines
############################################################################
#
# File: empg.icn
#
# Subject: Program to produce expression-benchmark program
#
# Author: Ralph E. Griswold
#
# Date: September 20, 1991
#
###########################################################################
#
# This program reads Icon expressions, one per line, and writes out
# an Icon program, which when run, times the expressions and reports
# average evaluation time and storage allocation.
#
# Lines beginning with a # are treated as comments and written to the
# output program so as to be written as comments when the output program is
# run.
#
# Lines beginning with a : are passed to the output program to be
# evaluated, but not timed.
#
# Lines beginning with a $ are included at the end of the output
# program as declarations.
#
# All other lines are timed in loops.
#
# An example of input is:
#
# :T := table(0)
# $record complex(r,i)
# T[1]
# complex(0.0,0.0)
#
# The resulting output program evaluates the expressions on the last two
# lines and reports their average time and storage allocation.
#
# The input file is specified on the command line. The output file
# is written to a file of the same base name, but with the suffix .icn.
# For example.
#
# iconx empg foo.exp
#
# reads input from foo.exp and writes output to foo.icn.
#
# This program can be configured to produce output to run under either the
# Icon interpreter or the Icon compiler. Some defaults differ for the two
# cases.
#
# The options are:
#
# -c configure for the compiler
#
# -f s flags for the executing program (only useful with -x
# option below)
#
# -i configure for the interpreter (the default)
#
# -o n number of iterations for computing loop overhead; the default
# for the interpreter is 10000, for the compiler 1000000
#
# -t n number of iterations for timing expressions; the default
# for the interpreter is 10000, for the compiler 100000
#
# -x run the output program
#
# The number of iterations for timing can be overridden on the command
# line when the output program is run. For example, in
#
# icont test
# iconx test 5000
#
# the expressions in test.icn are timed using 5000 iterations.
#
# If a garbage collection occurs during timing, the average time is
# likely to be significantly distorted and average allocation cannot be
# computed. In this case, the number of garbage collections is reported
# instead. To avoid misleading results as a consequence, measurement
# programs should be run with Icon's region sizes set to as large values
# as possible. To avoid residual effects of one timed expression on
# another, expressions that allocate significant amounts of storage
# should be measured in separate programs.
#
# The number of iterations used to compute loop overhead im empg
# and the number of iterations used to time expressions in measurement
# programs should be chosen so that the effects of low clock resolution
# are minimized. In particular, systems with very fast CPUs but
# low clock resolution (like 386 and 486 processors running under
# MS-DOS) need large values.
#
############################################################################
#
# Links: options
#
# Links: numbers (in the output program, not in empg.icn)
#
############################################################################
link options
procedure main(argl)
local i, decls, line, input, output, opts, processor, over, timing, run
local name, flags
opts := options(argl,"if:co+t+x")
processor := \opts["c"] # if interpreter, null
flags := (\opts["f"] | "") # flags for command line
if \opts["i"] then processor := &null # interpreter overrides
over := \opts["o"]
/over := if /processor then 10000 else 1000000
timing := \opts["t"]
/timing := if /processor then 10000 else 100000
run := opts["x"] # don't run if null
input := open(name := argl[1]) | stop("*** cannot open input file ***")
name ?:= {
tab(upto('.') | 0)
}
output := open(name || ".icn","w") | stop("*** cannot open output file ***")
decls := [] # list for declarations
write(output,"link numbers")
write(output,"global _Count, _Coll, _Store, _Overhead, _Names")
write(output,"procedure main(argl)")
write(output," local _Iter, _T, _S, _Itime, _I")
write(output," _Iter := argl[1] | ",timing)
write(output," _Names := [\"static\",\"string\",\"block \"]")
write(output," write(\"iterations: \",_Iter)")
write(output," write(\"&version: \",&version)")
write(output," write(\"&host: \",&host)")
write(output," write(\"&dateline: \",&dateline)")
write(output," write(\"region sizes: \")")
write(output," _I := 1")
write(output," every _S := ®ions do {")
write(output," write(\" \",_Names[_I],\" \",_S)")
write(output," _I +:= 1")
write(output," }")
write(output," _Count := ",over)
write(output," _Itime := &time")
write(output," every 1 to _Count do { &null }")
write(output," _Overhead := real(&time - _Itime) / _Count")
if /processor then { # interpreter overhead
write(output," _Itime := &time")
write(output," every 1 to _Count do { &null & &null }")
write(output," _Overhead := real(&time - _Itime) / _Count - _Overhead")
}
write(output," _Count := _Iter")
while line := read(input) do
case line[1] of {
":": { # evaluate but do not time
write(output," ",line[2:0])
write(output," write(",image(line[2:0]),")")
}
"$": { # line of declaration
put(decls,line[2:0])
write(output," write(",image(line[2:0]),")")
}
"#": # comment
write(output," write(",image(line),")")
default: { # time in a loop
write(output," write(",image(line),")")
write(output," _Prologue()")
write(output," _Itime := &time")
write(output," every 1 to _Count do {")
write(output," &null & ", line)
write(output," }")
write(output," _Epilogue(&time - _Itime)")
}
}
write(output,"end")
write(output,"procedure _Prologue()")
write(output," _Store := []")
write(output," _Coll := []")
write(output," collect()")
write(output," every put(_Store,&storage)")
write(output," every put(_Coll,&collections)")
write(output,"end")
write(output,"procedure _Epilogue(_Time)")
write(output," local _I")
write(output," every put(_Store,&storage)")
write(output," every put(_Coll,&collections)")
write(output," write(fix(real(_Time) / _Count - _Overhead,1,8,5),\" ms.\")")
write(output," if _Coll[1] = _Coll[5] then {")
write(output," write(\"average allocation:\",)")
write(output," every _I := 1 to 3 do")
write(output," write(\" \",_Names[_I],fix(real(_Store[_I + 3] - _Store[_I]),_Count,12,5))")
write(output," }")
write(output," else {")
write(output," write(\"garbage collections:\")")
write(output," write(\" total \",right(_Coll[5] - _Coll[1],4))")
write(output," every _I := 6 to 8 do write(\" \",_Names[_I - 5],right(_Coll[_I] - _Coll[_I - 4],4))")
write(output," write(\"region sizes: \")")
write(output," _I := 1")
write(output," every _S := ®ions do {")
write(output," write(\" \",_Names[_I],\" \",_S)")
write(output," _I +:= 1")
write(output," }")
write(output," }")
write(output," write()")
write(output,"end")
every write(output,!decls) # write out declarations
if \run then {
if \processor then system("iconc -s "|| flags || " " || name)
else system("icont -s " || flags || " " || name)
system(name)
}
end